package top.infopub.tdp.sys.service.impl;


import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.locks.ReentrantReadWriteLock;

import javax.annotation.PostConstruct;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import top.infopub.concurrent.ExecutorManager;
import top.infopub.generic.GenericDao;
import top.infopub.generic.GenericServiceImpl;
import top.infopub.model.sys.BusinessParameter;
import top.infopub.tdp.domain.BizParameterDomain;
import top.infopub.tdp.sys.dao.BizParameterDao;
import top.infopub.tdp.sys.service.BizParameterService;
import top.infopub.zookeeper.confclient.listener.ConfigurationListener;

/**
 * 业务参数服务
 * @author Awoke
 * @version 2018年9月20日
 * @see BizParameterServiceImpl
 * @since
 */
@Service("bizParameterService")
public class BizParameterServiceImpl extends GenericServiceImpl<BusinessParameter, String> implements BizParameterService, ConfigurationListener {

    private static Logger LOGGER = LoggerFactory.getLogger(BizParameterServiceImpl.class);

    @Autowired
    private BizParameterDao businessParameterDao;

    /** k-v nama/key-bean **/
    private Map<String, BizParameterDomain> caches = null;

    private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();

    @Override
    public GenericDao<BusinessParameter, String> getDao() {
        return businessParameterDao;
    }

    /**
     * 根据key取得值
     * @param key
     * @return
     */
    public String getValue(String key) {
        if (caches == null || StringUtils.isEmpty(key)) {
            return null;
        }
        try {
            lock.readLock().lock();
            BizParameterDomain _d = caches.get(key);
            if (_d == null) {
                return null;
            }
            return _d.getValue();
        }
        catch (Exception e) {
            LOGGER.error("", e);
            return null;
        }
        finally {
            lock.readLock().unlock();
        }
    }

    /**
     * 根据key取得bean
     * @param key
     * @return
     */
    public BizParameterDomain getParamObj(String key) {
        if (caches == null || StringUtils.isEmpty(key)) {
            return null;
        }
        try {
            lock.readLock().lock();
            BizParameterDomain _d = caches.get(key);
            if (_d == null) {
                return null;
            }
            BizParameterDomain dest = new BizParameterDomain();
            BeanUtils.copyProperties(dest, _d);
            return dest;
        }
        catch (Exception e) {
            LOGGER.error("", e);
            return null;
        }
        finally {
            lock.readLock().unlock();
        }
    }

    @PostConstruct
    public void loadDataDict() {
        ExecutorManager.getInstance().execute(new Runnable() {
            @Override
            public void run() {
                List<BizParameterDomain> result = null;
                try {
                    lock.writeLock().lock();
                    caches = new HashMap<String, BizParameterDomain>();
                    result = businessParameterDao.selectAll();
                    initCacheInfo(result);
                }
                finally {
                    lock.writeLock().unlock();
                }
            }
        });
    }

    private void initCacheInfo(List<BizParameterDomain> sysParams) {
        if (sysParams != null && !sysParams.isEmpty()) {
            for (BizParameterDomain dicDomain : sysParams) {
                // db-name作为key
                caches.put(dicDomain.getName(), dicDomain);
            }
        }
    }

    @Override
    public void configurationChangedNotice(String keyName, String value) {
        // 重新加载缓存数据 
        if (ZK_NAME.equalsIgnoreCase(keyName)) {
            loadDataDict();
        }
    }

}